#include <stdlib.h>
#include<stdio.h>
#include <errno.h>
#include <string.h>
#include "include/list_use_lock.h"
#include "include/xml_base.h"
#include "include/share_socket.h"
#include "include/sdk_net_base.h"

#define NETWAITIME 3000
#define NETWAITNUM 3


#define NET_MAX_LEN (8192+1024)
#define NET_CHECHK_PC_IDEENTIFIER_FIRST_BIT	    '@'
#define NET_CHECHK_PC_IDEENTIFIER_SECOND_BIT	 	'#'
#define NET_CHECHK_PC_IDEENTIFIER_THIRD_BIT 		'$'
#define NET_CHECHK_PC_IDEENTIFIER_FOURTH_BIT		'&'

#define  NET_MSG_HEAD_VERSION			(2015)

#define IS_FILE 0x1//保留位置第一位代表是文件


typedef struct Net_Opreate_Hanle
{
	int socket;
	OfferUserMessege_t usermessege;
	Xml_DocPtr_t pSendXmlHandle;
	Xml_DocPtr_t pRecvXmlHandle;
	char* pRecvMessege;
	InparamClientNet_t inParam;
	pthread_t client_tid;
	pthread_t heart_tid;
	pthread_t send_tid;//异步发送时用
	List_LockHandle_t* asynchronous_sendlist;//异步发送链表
	pthread_mutex_t lock;//互斥锁
	pthread_mutex_t netlock;//网络互斥锁
	Net_Status_t status;
	void *serverHandle;//如果是服务器，则此为服务器句柄
	void *serverClientParam;//如果是服务器，则代表连接后用户自己设置进来的指针，方便用户管理
	Net_Msg_Head_t headbuf;
}Net_Opreate_Hanle_t;


typedef struct Net_Server_Handle
{
	int serversocket;
	int nConnectNum;//连接的个数
	pthread_mutex_t serverlock;//互斥锁
	InparamServerNet_t inParam;
	pthread_t servertid;
	List_Handle_t pListClient;
	int serverStatus;
}Net_Server_Handle_t;


typedef struct Asynchronous_Info
{
	char *messege;
	int nLen;
	int code;
}Asynchronous_Info_t;
typedef enum
{
	SERVER_STAR = 0,
	SERVER_STOP,
	SERVER_ABOR,
}ServerStaus_t;
int free_asynchronous_sendmessege(Asynchronous_Info_t * asynchronous_sendmessege);
static void * net_clientsend_Thread(void *argv);
static int getclientsocket(Net_Opreate_Hanle_t *pNetHandle);

void *manag_malloc(size_t size)
{
	return malloc(size);
}
void manag_free(void *ptr)
{
	return free(ptr);
}
int usleep(int usec)
{
	int msec = usec / 1000;
	if (msec < 1)
	{
		msec = 1;
	}
	Sleep(msec);
	return 0;
}
int sdk_pthread_create(pthread_t *thread_id,const pthread_attr_t *user_attr, pthread_fun_sdk funtion, void *argv)
{

	  int ret ,stacksize = 128000; /*thread 堆栈设置为128K，stacksize以字节为单位。*/
	  pthread_attr_t attr;
	  ret = pthread_attr_init(&attr); /*初始化线程属性*/
	  if (ret != 0)
	      return -1;
	  ret = pthread_attr_setstacksize(&attr, stacksize);
	  if(ret != 0)
	  {
		  pthread_attr_destroy(&attr); /*不再使用线程属性，将其销毁*/
		  return -1;
	  }

	  ret = pthread_create (thread_id, &attr, funtion, argv);
	  if(ret != 0)
	  {
		  pthread_attr_destroy(&attr); /*不再使用线程属性，将其销毁*/
		  return -1;
	  }

	  ret = pthread_attr_destroy(&attr); /*不再使用线程属性，将其销毁*/
	  if(ret != 0)
	  {
		  return -1;
	  }


	return 0;
}
int getUsermessege(Sdk_Net_Handle_t clienthandle, OfferUserMessege_t * messege)
{
	Net_Opreate_Hanle_t* pclientHandle = (Net_Opreate_Hanle_t*)clienthandle;
	if(messege == NULL || pclientHandle == NULL)
	{
		return -1;
	}
	memcpy(messege, &(pclientHandle->usermessege), sizeof(OfferUserMessege_t));
	return 0;
}

int setConnectClientParam(Sdk_Net_Handle_t clienthandle, void*clientParam)
{
	Net_Opreate_Hanle_t* pclientHandle = (Net_Opreate_Hanle_t*)clienthandle;
	if(pclientHandle == NULL)
	{
		return -1;
	}
	pthread_mutex_lock(&(pclientHandle->lock));
	pclientHandle->serverClientParam = clientParam;
	pthread_mutex_unlock(&(pclientHandle->lock));
	return 0;
}
void* getConnectClientParam(Sdk_Net_Handle_t clienthandle)
{
	Net_Opreate_Hanle_t* pclientHandle = (Net_Opreate_Hanle_t*)clienthandle;
	void *clientParam = NULL;
	if(pclientHandle == NULL)
	{
		return NULL;
	}
	pthread_mutex_lock(&(pclientHandle->lock));
	clientParam = pclientHandle->serverClientParam;
	pthread_mutex_unlock(&(pclientHandle->lock));
	return clientParam;
}


static int setServerStatus(Net_Server_Handle_t *handle, ServerStaus_t status)
{
	if(handle == NULL)
	{
		return -1;
	}
	pthread_mutex_lock(&(handle->serverlock));
	handle->serverStatus = status;
	pthread_mutex_unlock(&(handle->serverlock));
	return 0;
}
static ServerStaus_t getServerStatus(Net_Server_Handle_t *handle)
{
	ServerStaus_t status = SERVER_ABOR;
	if(handle == NULL)
	{
		return status;
	}
	pthread_mutex_lock(&(handle->serverlock));
    status = (ServerStaus_t)handle->serverStatus;
	pthread_mutex_unlock(&(handle->serverlock));
	return status;
}

static int addServeConNum(Net_Server_Handle_t *handle)
{
	if(handle == NULL)
	{
		return -1;
	}
	pthread_mutex_lock(&(handle->serverlock));
	handle->nConnectNum++;
	pthread_mutex_unlock(&(handle->serverlock));
	return 0;
}
static int getServeConNum(Net_Server_Handle_t *handle)
{
	int nConnectNum = 0;
	if(handle == NULL)
	{
		return -1;
	}
	pthread_mutex_lock(&(handle->serverlock));
	nConnectNum = handle->nConnectNum;
	pthread_mutex_unlock(&(handle->serverlock));
	return nConnectNum;
}
static int subServeConNum(Net_Server_Handle_t *handle)
{
	if(handle == NULL)
	{
		return -1;
	}
	pthread_mutex_lock(&(handle->serverlock));
	handle->nConnectNum--;
	pthread_mutex_unlock(&(handle->serverlock));
	return 0;
}
static int net_init_head(Net_Msg_Head_t *head);
static Net_Status_t getclientstatus(Net_Opreate_Hanle_t *pNetHandle);
static int setclientsocket(Net_Opreate_Hanle_t *pNetHandle, int socket);

int sdknet_TcpSndNonblockFd(int Fd, char *SndBuf, int *SndLen, int Timeout, Net_Opreate_Hanle_t* pNetHandle)
{

	if(Fd < 0 || NULL == SndBuf || SndLen == NULL || pNetHandle == NULL) {
		//nslog(NS_ERROR, "<sdknet_TcpSndNonblockFd IS ERROR> <FD : %d> <SndBuf :%p> <SndLen :%p> <Timeout :%d>\n",
//		      Fd, SndBuf, SndLen, Timeout);
		return RHRETFAIL;
	}

	if(*SndLen < 0 || *SndLen == 0) {
		//nslog(NS_ERROR, "<sdknet_TcpSndNonblockFd IS ERROR> <FD : %d> <SndBuf :%p> <SndLen :%d> <Timeout :%d>\n",
//		      Fd, SndBuf, *SndLen, Timeout);
	}

    int _try = 0;
	int RetSelect   = -1;
	int SndTotalLen = 0;
	int SndBytes	= 0;
	int SndTempLen  = *SndLen;
	*SndLen = 0;
	fd_set SndSet;
	struct timeval Time;
	FD_ZERO(&SndSet);
	FD_SET(Fd, &SndSet);

	//    Time.tv_sec = Timeout;
	//    Time.tv_usec = 0;

	//int sendlenNum = 0;
	while(SndTotalLen < SndTempLen) {
		if(Timeout < 0) {
			RetSelect = select(Fd + 1, NULL, &SndSet, NULL, NULL);
		} else {
			Time.tv_sec = Timeout / 1000;
			Time.tv_usec = 1000 * (Timeout % 1000);

			RetSelect = select(Fd + 1, NULL, &SndSet, NULL, &Time);
		}


		if(RetSelect < 0) {
			//nslog(NS_ERROR, "<sdknet_TcpSndNonblockFd IS ERROR> <select> <ERROR_S :%s> <ERROR_D :%d> <FD : %d>\n",
			  //    strerror(errno), errno, Fd);
			return RH_GetPrivateError();
		} else if(RetSelect == 0) {
			//nslog(NS_ERROR, "<RH_TcpSndNonblockFd IS ERROR> <Snd timeout> <ERROR_S :%s> <ERROR_D :%d> <FD : %d> <Timeout :%d>\n",
			      ///strerror(errno), errno, Fd, Timeout);
			//return RH_GetPrivateError();
                if(_try++ > 5 || getclientsocket(pNetHandle) < 3)
				{
                    ///nslog(NS_ERROR, "<sdknet_TcpSndNonblockFd IS ERROR> <Snd timeout> <ERROR_S :%s> <ERROR_D :%d> <FD : %d> <Timeout :%d> _try:%d\n",
                    //			      strerror(errno), errno, Fd, Timeout, _try);
					return RH_GetPrivateError();
				}
				continue;

		} else {
			if(FD_ISSET(Fd, &SndSet)) {
		/*		if(SndTempLen - *SndLen < SENDMTU)
				{
					sendlenNum = SndTempLen - *SndLen;
				}
				else
				{
					sendlenNum = SENDMTU;
				}
				SndBytes = send(Fd , SndBuf + SndTotalLen, sendlenNum, 0);
		*/
				SndBytes = send(Fd , SndBuf + SndTotalLen, SndTempLen - SndTotalLen, 0);
				if(SndBytes <= 0) {
				//	nslog(NS_ERROR, "<sdknet_TcpSndNonblockFd IS ERROR> <Snd > <sendlen :%d> <ERROR_S :%s> <ERROR_D :%d> <FD : %d>\n",
				//	      SndTempLen - SndTotalLen, strerror(errno), errno, Fd);
					return RH_GetPrivateError();
				} else {
					SndTotalLen += SndBytes;
					*SndLen = SndTotalLen;
				}
			} else {
				//nslog(NS_ERROR, "<sdknet_TcpSndNonblockFd IS ERROR> <FD_ISSET> <ERROR_S :%s> <ERROR_D :%d> <FD : %d>\n",
				//      strerror(errno), errno, Fd);
				return RH_GetPrivateError();
			}
		}
	}

	return 	RHRETSUCCESS;
}
int net_send_msgdeal(Sdk_Net_Handle_t pOprHandle, char* message, int nLen, int code)
{

	Net_Msg_Head_t head_s;
	Net_Opreate_Hanle_t* pNetHandle = (Net_Opreate_Hanle_t*)pOprHandle;
	int ret = RHRETSUCCESS;
	int sendlen = 0;
	int socket = 0;


	if (pNetHandle == NULL || message == NULL || nLen <= 0)
	{
		//nslog(NS_ERROR, "pNetHandle is NULL, communication_send_msg failed\n");
		return -1;
	}
	socket = getclientsocket(pNetHandle);
	if(socket < 3)
	{
		return -1;
	}
	net_init_head(&head_s);
	head_s.msg_code = code;
	head_s.load_len = nLen;
	head_s.reserve = pNetHandle->headbuf.reserve;
	sendlen = sizeof(Net_Msg_Head_t);
	pthread_mutex_lock(&(pNetHandle->netlock));
	ret =  sdknet_TcpSndNonblockFd(socket, (char *)(&head_s), &sendlen, pNetHandle->inParam.overtime, pNetHandle);
	if (ret != RHRETSUCCESS)
	{
		//nslog(NS_DEBUG, "1 RH_TcpSndNonblockFd********* ret :%d pNetHandle->inParam.nPort:%d\n", ret, pNetHandle->inParam.nPort);
        goto _EXIT;
	}

	sendlen = nLen;
	ret = sdknet_TcpSndNonblockFd(socket, message, &sendlen, pNetHandle->inParam.overtime, pNetHandle);
	if (ret != RHRETSUCCESS)
	{
		//nslog(NS_DEBUG, "2 RH_TcpSndNonblockFd********* ret :%d pNetHandle->inParam.nPort:%d\n", ret, pNetHandle->inParam.nPort);
        goto _EXIT;
	}

_EXIT:
	pthread_mutex_unlock(&(pNetHandle->netlock));

	return ret;
}
int net_recv_msg(Sdk_Net_Handle_t pOprHandle, char* message, int nLen, int waitTime)
{
	Net_Opreate_Hanle_t* pNetHandle = (Net_Opreate_Hanle_t*)pOprHandle;
	int ret = 0;
	if (pNetHandle == NULL || message == NULL || nLen <= 0)
	{
		//nslog(NS_ERROR, "pNetHandle is NULL, communication_send_msg failed\n");
		return -1;
	}
	pthread_mutex_lock(&(pNetHandle->netlock));
	ret = RH_TcpRcvNonblockFd(pNetHandle->socket, message, &(nLen), waitTime);
	if (ret != RHRETSUCCESS || nLen == 0)
	{

	}

	pthread_mutex_unlock(&(pNetHandle->netlock));
	return ret;

}
int net_send_file(Sdk_Net_Handle_t pOprHandle, char* filename,  int code)
{
	Net_Msg_Head_t head_s;
	Net_Opreate_Hanle_t* pNetHandle = (Net_Opreate_Hanle_t*)pOprHandle;
	int ret = RHRETSUCCESS;
	int sendlen = 0;
	int socket = 0;

	FILE* filefd;
	unsigned long long nLen = 0;
	int nFreadSize = 0;
	char pBuf[1024] =  {0};

	if (pNetHandle == NULL || filename == NULL )
	{
		//nslog(NS_ERROR, "pNetHandle is NULL, communication_send_msg failed\n");
		return -1;
	}
	socket = getclientsocket(pNetHandle);
	if(socket < 3)
	{
		return -1;
	}


	{



		if ( NULL == (filefd = fopen(filename, "r")))
		{
			//nslog(NS_ERROR,"net_send_file fopen");
			return -1;
		}

		if(-1 == fseek(filefd, 0 ,SEEK_END)) /* 定位到文件末尾 */
		{
			//nslog(NS_ERROR,"net_send_file fseek END");
			fclose(filefd);
			return -1;
		}
		nLen = ftell(filefd); /* 得到文件大小 */
		if(nLen <= 0)
		{
			//nslog(NS_ERROR,"net_send_file fileName is Error");
			return -1;
		}
		if(-1 == fseek(filefd, 0 ,0)) /* 定位到文件末尾 */
		{
			//nslog(NS_ERROR,"net_send_file fseek END");
			fclose(filefd);
			return -1;
		}

	}
	net_init_head(&head_s);
	head_s.msg_code = code;
	head_s.reserve = IS_FILE;//第一位代表是文件类型，接收端好判断
	head_s.load_len = nLen;





	sendlen = sizeof(Net_Msg_Head_t);
	pthread_mutex_lock(&(pNetHandle->netlock));
	ret =  sdknet_TcpSndNonblockFd(socket, (char *)(&head_s), &sendlen, pNetHandle->inParam.overtime, pNetHandle);
	if (ret != RHRETSUCCESS)
	{
		//nslog(NS_DEBUG, "1 RH_TcpSndNonblockFd********* ret :%d pNetHandle->inParam.nPort:%d\n", ret, pNetHandle->inParam.nPort);
        goto _EXIT;
	}

	while(1)
	{
		nLen = sizeof(pBuf);
		nFreadSize = fread(pBuf, 1, nLen, filefd);
		sendlen = nFreadSize;
		ret = sdknet_TcpSndNonblockFd(socket, pBuf, &sendlen, pNetHandle->inParam.overtime, pNetHandle);
		if (ret != RHRETSUCCESS)
		{
			//nslog(NS_DEBUG, "2 RH_TcpSndNonblockFd********* ret :%d pNetHandle->inParam.nPort:%d\n", ret, pNetHandle->inParam.nPort);
			break;
		}
		if(nLen != nFreadSize)
		{

			if(feof(filefd))
			{
				//nslog(NS_INFO,"the fileis end\n");
				break;
			}
			else
			{
				//nslog(NS_ERROR,"read error\n");
				ret = -1;
				break;
			}
		}
	}

_EXIT:
	fclose(filefd);
	pthread_mutex_unlock(&(pNetHandle->netlock));

	return ret;
}
int net_send_msg(Sdk_Net_Handle_t pOprHandle, char* message, int nLen, int code)
{
	Net_Msg_Head_t head_s;
	Net_Opreate_Hanle_t* pNetHandle = (Net_Opreate_Hanle_t*)pOprHandle;
	int ret = RHRETSUCCESS;
	int sendlen = 0;
	int socket = 0;
	if (pNetHandle == NULL || message == NULL || nLen <= 0)
	{
		//nslog(NS_ERROR, "pNetHandle is NULL, communication_send_msg failed\n");
		return -1;
	}
	socket = getclientsocket(pNetHandle);
	if(socket < 3)
	{
		return -1;
	}

	//异步发送
	if(pNetHandle->inParam.asynchronous == 1)
	{
		//return 0;
		int size = 0;
		int listsize = 0;
		Asynchronous_Info_t * asynchronous_messege = NULL;
		List_LockHandle_t* pHeadHandle = NULL;

		pHeadHandle = pNetHandle->asynchronous_sendlist;

		listsize = pNetHandle->inParam.asynchronous_listnum;
		if(listsize <= 0 || listsize > 50)
		{
			listsize = 15;
		}

		if(( size = list_lockAndGet_size(pHeadHandle)) > listsize)
		{
		//	nslog(NS_DEBUG, "net_send_msg listsize is too large: :%d, pleaase check network port:%d\n", size, pNetHandle->inParam.nPort);
			return -1;
		}

		asynchronous_messege = (Asynchronous_Info_t*)manag_malloc(sizeof(Asynchronous_Info_t));
		if(asynchronous_messege == NULL)
		{
			return -1;
		}
        asynchronous_messege->messege = (char*)manag_malloc(nLen);
		if(asynchronous_messege->messege == NULL)
		{
			 manag_free(asynchronous_messege);
			return -1;
		}
		memcpy(asynchronous_messege->messege, message, nLen);
		asynchronous_messege->code = code;
		asynchronous_messege->nLen = nLen;

		list_lockAndPush_backSignal(pHeadHandle, asynchronous_messege);
		return 0;
	}

	net_init_head(&head_s);
	head_s.msg_code = code;
	head_s.load_len = nLen;
	head_s.reserve = pNetHandle->headbuf.reserve;
	//printf("head_s.load_len = nLen:%d\n", nLen);
	
	sendlen = sizeof(Net_Msg_Head_t);
	pthread_mutex_lock(&(pNetHandle->netlock));
	ret =  sdknet_TcpSndNonblockFd(socket, (char *)(&head_s), &sendlen, pNetHandle->inParam.overtime, pNetHandle);
	if (ret != RHRETSUCCESS)
	{
	//	nslog(NS_DEBUG, "1 RH_TcpSndNonblockFd********* ret :%d pNetHandle->inParam.nPort:%d\n", ret, pNetHandle->inParam.nPort);
        goto _EXIT;
	}

	sendlen = nLen;
	ret = sdknet_TcpSndNonblockFd(socket, message, &sendlen, pNetHandle->inParam.overtime, pNetHandle);
	if (ret != RHRETSUCCESS)
	{
	//	nslog(NS_DEBUG, "2 RH_TcpSndNonblockFd********* ret :%d pNetHandle->inParam.nPort:%d\n", ret, pNetHandle->inParam.nPort);
        goto _EXIT;
	}
	
_EXIT:
	pthread_mutex_unlock(&(pNetHandle->netlock));

	return ret;
}
void* sdk_list_begin_clientHandle(Sdk_ServerNet_Handle_t pServerHandle,
		Sdk_Net_Handle_t *pOprHandle)
{
    Net_Server_Handle_t* pNetServerHandle = (Net_Server_Handle_t*)pServerHandle;
	List_CurNode_t *pFindNode = NULL;
    pFindNode =  (List_CurNode_t *)list_begin(pNetServerHandle->pListClient);
	if(pFindNode != NULL)
	{
		*pOprHandle = ((DataNode*)pFindNode)->pData;
	}
	return pFindNode;
}
void* sdk_list_next_clientHandle(Sdk_ServerNet_Handle_t pServerHandle,
	Sdk_Net_Handle_t *pOprHandle, void* listNode)
{
    Net_Server_Handle_t* pNetServerHandle = (Net_Server_Handle_t*)pServerHandle;
	List_CurNode_t *pFindNode = NULL;
    pFindNode =  (List_CurNode_t *)list_next(pNetServerHandle->pListClient, listNode);
	if(pFindNode != NULL)
	{
		*pOprHandle = ((DataNode*)pFindNode)->pData;
	}
	return pFindNode;
}
void* sdk_list_end_clientHandle(Sdk_ServerNet_Handle_t pServerHandle)
{
    Net_Server_Handle_t* pNetServerHandle = (Net_Server_Handle_t*)pServerHandle;
	return list_end( pNetServerHandle->pListClient);
}
pthread_mutex_t* sdk_getlist_serverlock(Sdk_ServerNet_Handle_t pServerHandle)
{
    Net_Server_Handle_t* pNetServerHandle = (Net_Server_Handle_t*)pServerHandle;
	if(pNetServerHandle == NULL)
	{
		return NULL;
	}
	pthread_mutex_t *serverlock = &(pNetServerHandle->serverlock);
	return serverlock;
}
int netserver_send_allClient(Sdk_ServerNet_Handle_t pServerHandle, char* message, int nLen, int code)
{
    Net_Server_Handle_t* pNetServerHandle =(Net_Server_Handle_t*) pServerHandle;
	List_Handle_t pListClient = NULL;
	List_CurNode_t pFindNode = NULL;
	DataNode* pNode = NULL;
	int ret = 0;

	if(pNetServerHandle == NULL || message == NULL || nLen <= 0)
	{
		return -1;
	}

	pListClient = pNetServerHandle->pListClient;
	pthread_mutex_lock(&(pNetServerHandle->serverlock));
	for(pFindNode = list_begin(pListClient); pFindNode != list_end(pListClient); pFindNode = list_next(pListClient, pFindNode))
	{
		pNode = (DataNode*)pFindNode;
		ret = net_send_msg(pNode->pData, message, nLen, code);
		if(ret != RHRETSUCCESS)
		{
			break;
		}

	}
	pthread_mutex_unlock(&(pNetServerHandle->serverlock));

	return ret;

}
static int net_init_head(Net_Msg_Head_t *head)
{
	if (head == NULL)
	{
		return -1;
	}

	memset(head, 0, sizeof(Net_Msg_Head_t));
	//r_memcpy(head->identifier,Net_Msg_Head_IDENTIFIER,sizeof(head->identifier));
	head->identifier[0] = NET_CHECHK_PC_IDEENTIFIER_FIRST_BIT;
	head->identifier[1] = NET_CHECHK_PC_IDEENTIFIER_SECOND_BIT;
	head->identifier[2] = NET_CHECHK_PC_IDEENTIFIER_THIRD_BIT;
	head->identifier[3] = NET_CHECHK_PC_IDEENTIFIER_FOURTH_BIT;

	head->version = NET_MSG_HEAD_VERSION;
	return 0;
}


static Net_Status_t getclientstatus(Net_Opreate_Hanle_t *pNetHandle)
{
	Net_Status_t status;
	if (pNetHandle == NULL)
	{
		return SDK_NET_ERROR;
	}
	pthread_mutex_lock(&(pNetHandle->lock));
	status = pNetHandle->status;
	pthread_mutex_unlock(&(pNetHandle->lock));
	return status;
}
int setclientstatus(Net_Opreate_Hanle_t *pNetHandle, Net_Status_t status)
{
	if (pNetHandle == NULL)
	{
		return -1;
	}
	pthread_mutex_lock(&(pNetHandle->lock));
	pNetHandle->status = status;
	pthread_mutex_unlock(&(pNetHandle->lock));
	return 0;
}

static int getclientsocket(Net_Opreate_Hanle_t *pNetHandle)
{
	int socket = 0;
	if (pNetHandle == NULL)
	{
		return -1;
	}
	pthread_mutex_lock(&(pNetHandle->lock));
	socket = pNetHandle->socket;
	pthread_mutex_unlock(&(pNetHandle->lock));
	return socket;
}
static int setclientsocket(Net_Opreate_Hanle_t *pNetHandle, int socket)
{
	if (pNetHandle == NULL)
	{
		return -1;
	}
	pthread_mutex_lock(&(pNetHandle->lock));
	pNetHandle->socket = socket;
	pthread_mutex_unlock(&(pNetHandle->lock));
	usleep(10000);
	return 0;
}

static int client_check_netHead(Net_Msg_Head_t *head)
{
	if ((head == NULL) || (head->identifier[0] != NET_CHECHK_PC_IDEENTIFIER_FIRST_BIT)
		|| (head->identifier[1] != NET_CHECHK_PC_IDEENTIFIER_SECOND_BIT)
		|| (head->identifier[2] != NET_CHECHK_PC_IDEENTIFIER_THIRD_BIT)
		|| (head->identifier[3] != NET_CHECHK_PC_IDEENTIFIER_FOURTH_BIT))
	{
		return -1;
	}

	if (head->load_len <= 0)
	{
		return -1;
	}

	return 0;
}

static int dealCmd(NetCallbackMsg_t* dealmsg)
{

	Net_Opreate_Hanle_t *pNetHandle = NULL;
	if (dealmsg == NULL || dealmsg->sOperHandle == NULL)
	{
		return-1;
	}
	pNetHandle = (Net_Opreate_Hanle_t*)dealmsg->sOperHandle;
	InparamClientNet_t* pInParam = &(pNetHandle->inParam);

	if (pInParam->cmdfun)
	{
		dealmsg->InParam = pInParam->param;
		pInParam->cmdfun(dealmsg);
	}

	return 0;
}

static int destoryclient(Net_Opreate_Hanle_t *pNetHandle)
{
	Asynchronous_Info_t * asynchronous_sendmessege = NULL;
	if (pNetHandle)
	{
		if (pNetHandle->socket > 2)
		{
			RH_Close((char *)__FILE__, (char *)__func__, pNetHandle->socket);
		}
		pNetHandle->socket = -1;

		//防止正在发送
		pthread_mutex_lock(&(pNetHandle->lock));
		pthread_mutex_unlock(&(pNetHandle->lock));
		pthread_mutex_lock(&(pNetHandle->netlock));
		pthread_mutex_unlock(&(pNetHandle->netlock));
		pthread_mutex_destroy(&(pNetHandle->lock));
		pthread_mutex_destroy(&(pNetHandle->netlock));

		if(pNetHandle->asynchronous_sendlist)

		{
			//清空链表
			while(1)
			{
                asynchronous_sendmessege  = (Asynchronous_Info_t *)list_lockAndPop_front(pNetHandle->asynchronous_sendlist);
				if(asynchronous_sendmessege == NULL)
				{
					break;
				}
				free_asynchronous_sendmessege(asynchronous_sendmessege);
			}
			list_lockAndDestory(pNetHandle->asynchronous_sendlist);

		}
		 manag_free(pNetHandle);

		pNetHandle = NULL;
	}
	return 0;

}
static void* netclient_thread(void * argv)
{
	Net_Opreate_Hanle_t *pNetHandle = (Net_Opreate_Hanle_t*)argv;
	Net_Msg_Head_t headbuf;
	NetCallbackMsg_t dealmsg;
	InparamClientNet_t* pInParam = NULL;
	char * pRecvLongBuf = NULL;
	char recvshortBuf[NET_MAX_LEN];
	char *recvPoint = NULL;
	int ret = 0;
	int recvLen = 0;
	int noRecvTime = 0;
	int hearttime = NETWAITIME + 1000;
	int setstatus = 0;
	int socket = 0;
	int readlen = 0;
	int maxlongBufLen = 0;
	int creatsendthread = 0;
    int faddr_len = 0;
     struct sockaddr_in flocal;
     int errret = 0;
     int first_connect = 1;
#ifdef WIN32
	WORD wVersionRequested;
	WSADATA wsaData;
	wVersionRequested = MAKEWORD(1, 1);
	WSAStartup(wVersionRequested, &wsaData);
#endif
	if (pNetHandle == NULL)
	{
        goto _EXIT;
	}
	pInParam = &(pNetHandle->inParam);
RECONNECT:
	if(getclientstatus(pNetHandle) != SDK_NET_CONNECT)
	{
        goto _EXIT;
	}
	socket = getclientsocket(pNetHandle);
	if(socket > 2)
	{
		printf("reconnect\n");
		setclientsocket(pNetHandle, -1);
//		shutdown(socket, SHUT_RDWR);
		RH_Close((char *)__FILE__, (char *)__func__,  socket);
	}

	//因为服务器主动断开的才通知，连接不上的不通知
	if(pInParam->nReconnect && setstatus)
	{
		pNetHandle->inParam.statusFun(SDK_NET_DISCONNECT, pNetHandle, pInParam->param);
	}
	socket = RH_CreateTcpNoBindFd();
	if(socket < 3)
	{
		if(pInParam->nReconnect)
		{
			goto RECONNECT;
		}
        goto _EXIT;
	}
    ret = RH_ConnetNonblockFd(socket, pInParam->nPort, pInParam->ip, 4000);
	//printf("pInParam->nPort= %d,pInParam->ip=%s\n",pInParam->nPort,pInParam->ip);
	//exit(0);


	if (ret != RHRETSUCCESS || socket < 3)
	{

        if(first_connect == 1)
        {
            first_connect = 0;
            pNetHandle->inParam.statusFun(SDK_NET_DISCONNECT, pNetHandle, pInParam->param);
        }
		setstatus = 0;
		if(socket > 2)
		{
			setclientsocket(pNetHandle, -1);
			RH_Close((char *)__FILE__, (char *)__func__, socket);
		}
		if(getclientstatus(pNetHandle) != SDK_NET_CONNECT)
		{
            goto _EXIT;
		}
		sleep(2);
		pInParam->logFun("connect is fail ret:%d\n", ret);

		if(pInParam->nReconnect)
		{
			goto RECONNECT;
		}
        goto _EXIT;
	}
	setclientsocket(pNetHandle, socket);
	setstatus = 1;
	RH_SetSndTimeoutFd(socket , hearttime/1000, hearttime%1000);
	RH_SetRcvTimeoutFd(socket , hearttime/1000, hearttime%1000);
	pInParam->statusFun(SDK_NET_CONNECT, pNetHandle, pInParam->param);

      faddr_len = sizeof( struct sockaddr_in);

	  memset(&flocal , 0 ,sizeof(struct sockaddr_in));
	//  errret = getsockname(socket,(struct sockaddr*)&flocal, (socklen_t *)&faddr_len);
	  //printf("ip:%s port:%d pNetHandle->socket:%d ret:%d\n", inet_ntoa(flocal.sin_addr), ntohs(flocal.sin_port),socket, errret);
	  printf("ip:%s port:%d pNetHandle->socket:%d ret:%d\n", pInParam->ip, pInParam->nPort,socket, errret);

		if(pNetHandle->inParam.asynchronous == 1 && pNetHandle->asynchronous_sendlist == NULL)
		{
			pNetHandle->asynchronous_sendlist =  list_lockAndCreate();
			ret = sdk_pthread_create(&(pNetHandle->send_tid), NULL, net_clientsend_Thread, (void *)(pNetHandle));
			if(ret != 0)
			{
				pInParam->logFun(" netclient_thread sdk_pthread_create send_clientsetreamThread is fail\n");
                goto _EXIT;
			}
			creatsendthread = 1;
		}

	while (getclientstatus(pNetHandle) == SDK_NET_CONNECT)
	{
		memset(&headbuf, 0, sizeof(Net_Msg_Head_t));
		recvLen = sizeof(Net_Msg_Head_t);
		ret = RH_TcpRcvBlockFd(socket, (char *)(&headbuf), recvLen, &readlen);
		if (ret != RHRETSUCCESS || readlen != recvLen)
		{
			printf("************* readlen:%d ret:%d recvLen:%d\n", readlen, ret, recvLen);
			noRecvTime++;
			if (-ret == ECONNRESET || -ret == ECONNREFUSED)//连接被对方复位
			{
				pInParam->logFun("server is disconnect ret:%d\n", ret);
				if(pInParam->nReconnect)
				{
					//sleep(2);
					goto RECONNECT;
				}
                goto _EXIT;
			}
			if (noRecvTime >= NETWAITNUM)
			{
				pInParam->logFun("NETNoRecvTime>NETWAITNUM Heart Error buf is failed,the port=[%d]\n", ret);
				//socket 异常，断链退出。
				if(pInParam->nReconnect)
				{
					//sleep(2);
					goto RECONNECT;
				}
                goto _EXIT;
			}
			continue;
		}

		noRecvTime = 0;

		if (client_check_netHead(&headbuf) != 0)
		{
			pInParam->logFun("%s %s %d,communtication_check_head is failed,the port =.\n", WITH_ALL);
			if(pInParam->nReconnect)
			{
				//sleep(2);
				goto RECONNECT;
			}
            goto _EXIT;
		}

		//memset(recvshortBuf, 0, sizeof(recvshortBuf));
		if (headbuf.load_len >= NET_MAX_LEN)
		{
			if(headbuf.load_len > maxlongBufLen)
			{
				if(pRecvLongBuf)
				{
					 manag_free(pRecvLongBuf);
					pRecvLongBuf = NULL;
				}

				pRecvLongBuf = (char *)manag_malloc(headbuf.load_len);
				if (pRecvLongBuf == NULL)
				{
					pInParam->logFun("%s %s %d,malloc  long recvbuf is fail =.\n", WITH_ALL);
					if(pInParam->nReconnect)
					{
						//sleep(2);
						goto RECONNECT;
					}
                    goto _EXIT;
				}
				maxlongBufLen = headbuf.load_len;
			}

			recvPoint = pRecvLongBuf;
		}
		else
		{
			recvPoint = recvshortBuf;
			recvshortBuf[headbuf.load_len] = '\0';
		}

		ret = RH_TcpRcvBlockFd(socket, recvPoint, (headbuf.load_len), &readlen);
		if (ret != RHRETSUCCESS || readlen != headbuf.load_len)
		{
			pInParam->logFun("RH_TcpRcvNonblockFd is failed,the msg_code is [%d],\n", headbuf.msg_code);
			if(pInParam->nReconnect)
			{
				//sleep(2);
				goto RECONNECT;
			}
            goto _EXIT;
		}
		dealmsg.Code = headbuf.msg_code;
		dealmsg.sOperHandle = pNetHandle;
		dealmsg.recvvalue = recvPoint;
		dealmsg.nLen = headbuf.load_len;
		dealmsg.InParam = pNetHandle->inParam.param;
		pNetHandle->pRecvMessege = recvPoint;
		memset(&(pNetHandle->headbuf),0,sizeof(Net_Msg_Head_t));
		memcpy(&(pNetHandle->headbuf),&headbuf,sizeof(Net_Msg_Head_t));

		if(dealmsg.Code == SDK_NET_HEARTBIT_CMD)
		{
			if(pInParam->heartmsg != NULL)
			{

			}
			else
			{
				net_send_msgdeal(pNetHandle, dealmsg.recvvalue, dealmsg.nLen, SDK_NET_HEARTBIT_CMD);
			}

		}
		if (dealCmd(&dealmsg) != 0)
		{
			pInParam->logFun("dealCmd is failed,the msg_code is [%d],\n", headbuf.msg_code);
			if(pInParam->nReconnect)
			{
				//sleep(2);
				goto RECONNECT;
			}
            goto _EXIT;
		}
	}
_EXIT:
	if (pRecvLongBuf)
	{
		 manag_free(pRecvLongBuf);
		pRecvLongBuf = NULL;
	}
	if (pNetHandle)
	{

		socket = getclientsocket(pNetHandle);
		if(socket > 2)
		{
			RH_Close((char *)__FILE__, (char *)__func__, socket);
			setclientsocket(pNetHandle, -1);
		}
		setclientstatus(pNetHandle, SDK_NET_DISCONNECT);
		if(pNetHandle->inParam.asynchronous == 1 && creatsendthread == 1)
		{
			//nslog(NS_INFO, "pthread_join  pNetHandle->send_tid start\n");
			list_cond_signal(pNetHandle->asynchronous_sendlist);
			pthread_join(pNetHandle->send_tid, NULL);
		//	nslog(NS_INFO, "pthread_join  pNetHandle->send_tid end\n");
		}
		pNetHandle->inParam.statusFun(SDK_NET_DISCONNECT, pNetHandle, pInParam->param);
	}
	//pthread_detach(pthread_self());
	return NULL;
}
Sdk_Net_Handle_t sdkclient_init_net(InparamClientNet_t netparm)
{
	Net_Opreate_Hanle_t* pNetHandle = NULL;
	if (netparm.nPort <= 0 || netparm.logFun == NULL || netparm.overtime <= 0 || netparm.statusFun == NULL
		|| netparm.cmdfun == NULL)
	{
		return NULL;
	}

	pNetHandle = (Net_Opreate_Hanle_t*)manag_malloc(sizeof(Net_Opreate_Hanle_t));
	if (pNetHandle == NULL)
	{
		netparm.logFun("malloc Net_Opreate_Hanle_t is fail\n");
	}
	memset(pNetHandle, 0, sizeof(Net_Opreate_Hanle_t));
	memcpy(&(pNetHandle->inParam), &netparm, sizeof(InparamClientNet_t));
	
	pthread_mutex_init(&(pNetHandle->lock), NULL);
	pthread_mutex_init(&(pNetHandle->netlock), NULL);
	setclientstatus(pNetHandle, SDK_NET_CONNECT);
	int ret = sdk_pthread_create(&(pNetHandle->client_tid), NULL, netclient_thread, (void *)(pNetHandle));

	if (ret != 0)
	{
		netparm.logFun("crate NetCreateclint thread failed\n");
		 manag_free(pNetHandle);
		return NULL;
	}

	return pNetHandle;
}
RetErr_t sdknet_add_value(tar_messege_t messege,const char *keyname, Value_Type_t valuetype, void *value)

{
	RetErr_t ret = RET_SUCCESS;
	Net_Opreate_Hanle_t* pNetHandle = (Net_Opreate_Hanle_t*)messege.handle;
	if (pNetHandle == NULL || messege.valueHandle == NULL || keyname == NULL || value == NULL)
	{
		return RET_PARAMER_ERR;
	}

	if (*(messege.valueHandle) == NULL)
	{
		*(messege.valueHandle) = (void*)xml_init_doc();
	}
	if (valuetype == SDK_INT)
	{
		if (FALSE == xml_set_intNode1(keyname, *((int*)(value)), *(messege.valueHandle)))
		{
			pNetHandle->inParam.logFun("sdk_add_value xml set is fail\n");
			ret = RET_PARAMER_ERR;
		}
	}
	else if (valuetype == SDK_SHORT)
	{
		if (FALSE == xml_set_shortNode1(keyname, *((short*)(value)), *(messege.valueHandle)))
		{
			pNetHandle->inParam.logFun("xml_set_shortNode1 xml set is fail\n");
			ret = RET_PARAMER_ERR;
		}
	}
	else if (valuetype == SDK_CHAR)
	{
		if (FALSE == xml_set_charNode1(keyname, ((char*)(value)), *(messege.valueHandle)))
		{
			pNetHandle->inParam.logFun("sdk_add_value  xml_set_charNode1 fail\n");
			ret = RET_PARAMER_ERR;
		}
	}
	else if (valuetype == SDK_FLOAT)
	{
		if (FALSE == xml_set_floatNode1(keyname, *((float*)(value)), *(messege.valueHandle)))
		{
			pNetHandle->inParam.logFun("sdk_add_value xml xml_set_floatNode1 is fail\n");
			ret = RET_PARAMER_ERR;
		}
	}
	else if (valuetype == SDK_DOUBLE)
	{
		if (FALSE == xml_set_doubleNode1(keyname, *((double*)(value)), *(messege.valueHandle)))
		{
			pNetHandle->inParam.logFun("sdk_add_value xml xml_set_doubleNode1 is fail\n");
			ret = RET_PARAMER_ERR;
		}
	}
	else if (valuetype == SDK_FILE)
	{
		if (FALSE == xml_set_charNode1((char *)"/root/MsgBody/fileName/", ((char*)(value)), *(messege.valueHandle)))
		{
			pNetHandle->inParam.logFun("sdk_add_value  xml_set_charNode1 fail\n");
			ret = RET_PARAMER_ERR;
		}
	}
	else
	{
		pNetHandle->inParam.logFun("no support\n");
		ret = RET_NOT_EXIST;
	}

	return ret;
}
RetErr_t sdknet_send_value(Sdk_Net_Handle_t handle, void ** valueHandle, int code)
{
	RetErr_t ret = RET_SUCCESS;
	Net_Opreate_Hanle_t *pOprHandle = (Net_Opreate_Hanle_t*)handle;
	char * outBuf = NULL;
	if (pOprHandle == NULL || valueHandle == NULL || *valueHandle == NULL)
	{
		return RET_PARAMER_ERR;
	}
	xml_handleTo_str(*valueHandle, "UTF-8", &outBuf);
	if (outBuf == NULL)
	{
		ret = RET_PARSE_ERR;
		goto SENDEXIT;
	}
	//printf("\noutBuf = %s66666666\n",outBuf);
	if (0 == net_send_msg(pOprHandle, outBuf, strlen(outBuf), code))
	{
		ret = RET_SUCCESS;
		goto SENDEXIT;
	}
SENDEXIT:
	if (*valueHandle)
	{
		xml_free_docHandle(*valueHandle);
		*valueHandle = NULL;
	}
	if (outBuf)
	{
		xml_free_baseBuf(outBuf);
		outBuf = NULL;
	}
	return ret;
}
RetErr_t sdknet_get_value(tar_messege_t messege,const char *keyname, Value_Type_t valuetype, void *value, int nLen)
{
	RetErr_t ret = RET_SUCCESS;
	Net_Opreate_Hanle_t* pNetHandle = (Net_Opreate_Hanle_t*)messege.handle;
	if (pNetHandle == NULL || keyname == NULL || value == NULL || pNetHandle->pRecvMessege == NULL || messege.nodeindex < 0)
	{
		return RET_PARAMER_ERR;
	}

	if (valuetype == SDK_INT)
	{
		if (FALSE == xml_get_intNode3(keyname, ((int*)(value)), pNetHandle->pRecvMessege, messege.nodeindex))
		{
			pNetHandle->inParam.logFun("sdk_get_value xml get is fail\n");
			ret = RET_PARAMER_ERR;
		}
	}
	else if (valuetype == SDK_SHORT)
	{
		if (FALSE == xml_get_shortNode3(keyname, ((short*)(value)), pNetHandle->pRecvMessege, messege.nodeindex))
		{
			pNetHandle->inParam.logFun("sdk_get_value xml get is fail\n");
			ret = RET_PARAMER_ERR;
		}
	}
	else if (valuetype == SDK_CHAR)
	{
		if (FALSE == xml_get_charNode3(keyname, ((char*)(value)), pNetHandle->pRecvMessege, nLen, messege.nodeindex))
		{
			pNetHandle->inParam.logFun("sdk_get_value  xml_get_charNode1 fail\n");
			ret = RET_PARAMER_ERR;
		}
	}
	else if (valuetype == SDK_FLOAT)
	{
		if (FALSE == xml_get_floatNode3(keyname, ((float*)(value)), pNetHandle->pRecvMessege, messege.nodeindex))
		{
			pNetHandle->inParam.logFun("sdk_get_value xml xml_get_floatNode1 is fail\n");
			ret = RET_PARAMER_ERR;
		}
	}
	else if (valuetype == SDK_DOUBLE)
	{
		if (FALSE == xml_get_doubleNode3(keyname, ((double*)(value)), pNetHandle->pRecvMessege, messege.nodeindex))
		{
			pNetHandle->inParam.logFun("sdk_get_value xml xml_get_doubleNode1 is fail\n");
			ret = RET_PARAMER_ERR;
		}
	}
	else
	{
		pNetHandle->inParam.logFun("no support\n");
		ret = RET_NOT_EXIST;
	}

	return ret;
}
RetErr_t sdkclient_stop_net(Sdk_Net_Handle_t handle)
{
	Net_Opreate_Hanle_t *pOprHandle = (Net_Opreate_Hanle_t*)handle;
	RetErr_t ret = RET_SUCCESS;
	if (pOprHandle == NULL)
	{
		return RET_PARAMER_ERR;
	}
	setclientstatus(pOprHandle, SDK_NET_DISCONNECT);
#ifdef WIN32
	WSACleanup();
#endif
	return ret;
}
RetErr_t sdkclient_uninit_net(Sdk_Net_Handle_t handle)
{
	Net_Opreate_Hanle_t *pOprHandle = (Net_Opreate_Hanle_t*)handle;
	RetErr_t ret = RET_SUCCESS;
	int socket = 0;
	if (pOprHandle == NULL)
	{
		return RET_PARAMER_ERR;
	}
	pOprHandle->inParam.nReconnect = 0;
	setclientstatus(pOprHandle, SDK_NET_DISCONNECT);
	socket = getclientsocket(pOprHandle);
	if(socket > 2)
	{
		setclientsocket(pOprHandle, -1);
	//	shutdown(socket, SHUT_RDWR);
		RH_Close((char *)__FILE__, (char *)__func__, socket);
		printf("socket************ close:%d\n", socket);
	}
	pthread_join(pOprHandle->client_tid, NULL);
	destoryclient(pOprHandle);
#ifdef WIN32
	WSACleanup();
#endif
	return ret;
}






void * net_clientHeartThread(void *argv)
{
	Net_Opreate_Hanle_t* pOprHandle = (Net_Opreate_Hanle_t*)argv;
	Net_Server_Handle_t* serverHandle = NULL;
	InparamServerNet_t *inParam = NULL;
	char HeartBitBUF[2048] = {0};
	int time = NETWAITIME/1000;
	int sendLen = 0;
	int inputLen = sizeof(HeartBitBUF);
	if(time == 0)
	{
		time = 2;
	}
	if(pOprHandle == NULL || pOprHandle->serverHandle == NULL)
	{
		return NULL;
	}
	serverHandle = (Net_Server_Handle_t*)pOprHandle->serverHandle;
	inParam = &(serverHandle->inParam);
	while(getclientstatus(pOprHandle) == SDK_NET_CONNECT)
	{
		//发送心跳流程
		if(inParam->heartmsg != NULL)
		{
			inParam->heartmsg(HeartBitBUF, sizeof(HeartBitBUF), pOprHandle, inParam->param, &sendLen);
			if(sendLen <= 0 || sendLen > inputLen)
			{
				sendLen = inputLen;
			}
#if 1
			if (0 != net_send_msgdeal(pOprHandle, HeartBitBUF, sendLen, SDK_NET_HEARTBIT_CMD))
			{
				sleep(1);
				continue;
			}
#endif			
		}
		sleep(time);
	}
	//pthread_detach(pthread_self());
	pthread_exit(0);
	return NULL;
}
int free_asynchronous_sendmessege(Asynchronous_Info_t * asynchronous_sendmessege)
{
	if(asynchronous_sendmessege)
	{
		if(asynchronous_sendmessege->messege)
		{
			 manag_free(asynchronous_sendmessege->messege);
		}
		 manag_free(asynchronous_sendmessege);
	}
	return 0;
}
int sdk_netis_h264(unsigned char *pos, int nLen)
{
	//4个头自己再加上NAUL 8个字节
	if(nLen <= 12)
	{
		return 0;
	}

	if(!((*pos == 0 && *(pos + 1) == 0 && *(pos + 2) == 0 && *(pos + 3) == 1))) {
		return 0;    //not h264
	} else {
		return 1;    //is h264
	}
}
int sdk_netis_iframe(unsigned char *pos)
{
	if((pos[4] & 0xf) != 0x1)
	{
		return 1;
	}
	return 0;
}
void * net_clientsend_Thread(void *argv)
{
	Net_Opreate_Hanle_t* pOprHandle = (Net_Opreate_Hanle_t*)argv;
	int time = 0;
	Asynchronous_Info_t * asynchronous_sendmessege = NULL;
	List_LockHandle_t* pHeadHandle = NULL;
	int h264sendfail = 0;
	if(pOprHandle == NULL)
	{
		return NULL;
	}
	pHeadHandle = pOprHandle->asynchronous_sendlist;
	time = pOprHandle->inParam.asynchronous_time;
	if(time < 20)
	{
		time = 20;
	}
	if(time > 2000)
	{
		time = 2000;
	}
	//nslog(NS_INFO,RED "net_clientsend_Thread asynchronous_sendmessege is sucessful port:%d\n"NONE, pOprHandle->inParam.nPort);
	while(getclientstatus(pOprHandle) == SDK_NET_CONNECT)
	{
        asynchronous_sendmessege  = (Asynchronous_Info_t *)list_lockAndPop_frontSignal(pHeadHandle, time);
		if(asynchronous_sendmessege)
		{
			//发送失败做处理
			if(h264sendfail == 1)
			{
				if(sdk_netis_h264((unsigned char *)asynchronous_sendmessege->messege,asynchronous_sendmessege->nLen) == 1)
				{
					//将i帧发送，紧接着可以发送p帧
					if(sdk_netis_iframe((unsigned char *)asynchronous_sendmessege->messege) == 1)
					{
						h264sendfail = 0;
					}
					else
					{
						free_asynchronous_sendmessege(asynchronous_sendmessege);
						continue;
					}
				}
			}
			if (0 != net_send_msgdeal(pOprHandle, asynchronous_sendmessege->messege, asynchronous_sendmessege->nLen,
					asynchronous_sendmessege->code))
			{
				//h264发送失败得抛帧处理
				if(sdk_netis_h264((unsigned char *)asynchronous_sendmessege->messege, asynchronous_sendmessege->nLen) == 1)
				{
					h264sendfail = 1;
					//nslog(NS_ERROR, "net_send_msg is fail port:%d", pOprHandle->inParam.nPort);
				}

			}
		}
		free_asynchronous_sendmessege(asynchronous_sendmessege);
	}

	return 0;
}
static void * server_process_clientThread(void * argc)
{

		pthread_detach(pthread_self());
		static int numpth = 0;
		Net_Opreate_Hanle_t *pNetHandle = (Net_Opreate_Hanle_t*)argc;
		Net_Msg_Head_t headbuf;
		NetCallbackMsg_t dealmsg;
		InparamClientNet_t* pInParam = NULL;
		int creatheart = 0;
		int creatsend = 0;
		char * pRecvLongBuf = NULL;
		char recvshortBuf[NET_MAX_LEN];
		char *recvPoint = NULL;
		int ret = 0;
		int recvLen = 0;
		int noRecvTime = 0;
		int hearttime = NETWAITIME;
		Net_Server_Handle_t* serverHandle = NULL;
		int maxLongBufLen = 0;
	#ifdef WIN32
		WORD wVersionRequested;
		WSADATA wsaData;
		wVersionRequested = MAKEWORD(1, 1);
		WSAStartup(wVersionRequested, &wsaData);
	#endif
		if (pNetHandle == NULL)
		{
            goto _EXIT;
		}
		serverHandle = (Net_Server_Handle_t*)pNetHandle->serverHandle;



		pInParam = &(pNetHandle->inParam);
        //pInParam->logFun("clientip:%s is connect now connectnum:%d\n", pNetHandle->usermessege.ip, getServeConNum(pNetHandle->serverHandle));

		pthread_mutex_init(&(pNetHandle->lock), NULL);
		pthread_mutex_init(&(pNetHandle->netlock), NULL);

		setclientstatus(pNetHandle, SDK_NET_CONNECT);


		RH_SetSndTimeoutFd(pNetHandle->socket , hearttime/1000, hearttime%1000);
		RH_SetRcvTimeoutFd(pNetHandle->socket , hearttime/1000, hearttime%1000);

		pInParam->statusFun(SDK_NET_CONNECT, pNetHandle, pInParam->param);
		numpth++;
		ret = sdk_pthread_create(&(pNetHandle->heart_tid), NULL, net_clientHeartThread, (void *)(pNetHandle));
		if(ret != 0)
		{
			pInParam->logFun("sdk_pthread_create net_clientHeartThread is fail errno:%s numpth:%d ret:%d\n", strerror(errno), numpth, ret);
            goto _EXIT;
		}
		creatheart = 1;
		pNetHandle->inParam.asynchronous = serverHandle->inParam.asynchronous;
		pNetHandle->inParam.asynchronous_listnum = serverHandle->inParam.asynchronous_listnum;
		pNetHandle->inParam.nPort = serverHandle->inParam.nPort;
		pNetHandle->inParam.asynchronous_time = serverHandle->inParam.asynchronous_time;
		if(serverHandle->inParam.asynchronous == 1)
		{
			pNetHandle->asynchronous_sendlist =  list_lockAndCreate();
			ret = sdk_pthread_create(&(pNetHandle->send_tid), NULL, net_clientsend_Thread, (void *)(pNetHandle));
			if(ret != 0)
			{
				pInParam->logFun("sdk_pthread_create send_clientsetreamThread is fail\n");
                goto _EXIT;
			}
			usleep(200000);
			creatsend = 1;
		}


		pthread_mutex_lock(&(serverHandle->serverlock));
		list_push_back(serverHandle->pListClient, pNetHandle);
		pthread_mutex_unlock(&(serverHandle->serverlock));
		while (getclientstatus(pNetHandle) == SDK_NET_CONNECT)
		{

			memset(&headbuf, 0, sizeof(Net_Msg_Head_t));
			recvLen = sizeof(Net_Msg_Head_t);
			ret = RH_TcpRcvNonblockFd(pNetHandle->socket, (char *)(&headbuf), &recvLen, hearttime);
			if (ret != RHRETSUCCESS || recvLen <= 0)
			{
				noRecvTime++;
				if (-ret == ECONNRESET || -ret == ECONNREFUSED)//连接被对方复位
				{
					pInParam->logFun("server is disconnect ret:%d\n", ret);
                    goto _EXIT;
                }
				if (noRecvTime >= NETWAITNUM)
				{
					pInParam->logFun("NETNoRecvTime>NETWAITNUM Heart Error buf is failed,the port=%d ret=[%d]\n",serverHandle->inParam.nPort, ret);
					//socket 异常，断链退出。
                    goto _EXIT;
				}
				continue;
			}

			noRecvTime = 0;

			if (client_check_netHead(&headbuf) != 0)
			{
				pInParam->logFun("%s %s %d,communtication_check_head is failed,the port =.\n", WITH_ALL);
                goto _EXIT;
			}

			//memset(recvshortBuf, 0, sizeof(recvshortBuf));
			if (headbuf.load_len >= NET_MAX_LEN)
			{

				if(headbuf.load_len >= maxLongBufLen)
				{
					if (pRecvLongBuf)
					{
						 manag_free(pRecvLongBuf);
						pRecvLongBuf = NULL;
					}
					pRecvLongBuf = (char *)manag_malloc(headbuf.load_len);
					if (pRecvLongBuf == NULL)
					{
						pInParam->logFun("%s %s %d,malloc  long recvbuf is fail =.\n", WITH_ALL);
                        goto _EXIT;
					}
					maxLongBufLen = headbuf.load_len;
				}

				recvPoint = pRecvLongBuf;
			}
			else
			{
				recvPoint = recvshortBuf;
				recvshortBuf[headbuf.load_len] = '\0';
			}
			recvLen =  headbuf.load_len;
			ret = RH_TcpRcvNonblockFd(pNetHandle->socket, recvPoint, &(headbuf.load_len), hearttime);
			if (ret != RHRETSUCCESS || headbuf.load_len == 0)
			{
				pInParam->logFun("RH_TcpRcvNonblockFd is failed,the msg_code is [%d], headbuf.load_len:%d"
						"ret:%d recvLen:%d\n", headbuf.msg_code, headbuf.load_len, ret, recvLen);
                goto _EXIT;
			}
			dealmsg.Code = headbuf.msg_code;
			dealmsg.sOperHandle = pNetHandle;
			dealmsg.recvvalue = recvPoint;
			dealmsg.nLen = headbuf.load_len;
			pNetHandle->pRecvMessege = recvPoint;
			if (dealCmd(&dealmsg) != 0)
			{
				pInParam->logFun("dealCmd is failed,the msg_code is [%d],\n", headbuf.msg_code);
                goto _EXIT;
			}


		}
    _EXIT:
		if (pNetHandle)
		{
			if (pRecvLongBuf)
			{
				 manag_free(pRecvLongBuf);
				pRecvLongBuf = NULL;
			}
			if(serverHandle)
			{
				pthread_mutex_lock(&(serverHandle->serverlock));
				list_earse_data(serverHandle->pListClient, pNetHandle);
				pthread_mutex_unlock(&(serverHandle->serverlock));
			}
			setclientstatus(pNetHandle, SDK_NET_DISCONNECT);
			pInParam->statusFun(SDK_NET_DISCONNECT, pNetHandle, pNetHandle->inParam.param);

            subServeConNum((Net_Server_Handle_t *)pNetHandle->serverHandle);

			if(creatheart == 1)
			{
				pthread_join(pNetHandle->heart_tid, NULL);
			}

			if(serverHandle->inParam.asynchronous == 1 && creatsend == 1)
			{
				pthread_join(pNetHandle->send_tid, NULL);
			}
			int closesocket = 0;
			if((closesocket = getclientsocket(pNetHandle)) > 2)
			{
				setclientsocket(pNetHandle, -1);
			//	shutdown(closesocket, SHUT_RDWR);
				RH_Close((char *)__FILE__, (char *)__func__, closesocket);
			}
			destoryclient(pNetHandle);
		}
		numpth--;

	return NULL;
}


static void* netServer_thread(void * argc)
{
	Net_Server_Handle_t* serverHandle = (Net_Server_Handle_t*)argc;
	InparamServerNet_t* inParam = NULL;
	Net_Opreate_Hanle_t* pOprHandle = NULL;
	int client_socket = -1;
	pthread_t tid;
	int ret = 0;
	char clientip[16] = {0};
	if(serverHandle == NULL)
	{
        goto _EXIT;
	}
	inParam = &(serverHandle->inParam);
	serverHandle->serversocket = RH_CreateTcpBindFd(inParam->nPort, NULL);
	if(serverHandle->serversocket < 2)
	{
		inParam->logFun("server_socket create failed,port[%u].\n", inParam->nPort);
        goto _EXIT;
	}

	if(listen(serverHandle->serversocket , 30) < 0)
	{
		inParam->logFun("listen error:%d,error msg:=%s,port[%u].\n", errno, strerror(errno), inParam->nPort);
        goto _EXIT;
	}
	setServerStatus(serverHandle, SERVER_STAR);
	inParam->logFun("creat server is sucessful*********\n");
	while(getServerStatus(serverHandle) == SERVER_STAR)
	{

		client_socket = RH_GetConnectNonblockFd(serverHandle->serversocket, 5, clientip);
		if(client_socket > 2)
		{
			//当小于等于0默认不限制，来者不拒
			if((getServeConNum(serverHandle) >= inParam->nConnectMaxNum) && (inParam->nConnectMaxNum > 0))
			{
				inParam->logFun("maxConnectNum:%d nowConnectNum\n",inParam->nConnectMaxNum ,  getServeConNum(serverHandle));
				continue;
			}
			pOprHandle =(Net_Opreate_Hanle_t*) manag_malloc(sizeof(Net_Opreate_Hanle_t));
			if(pOprHandle == NULL)
			{
				//nslog(NS_ERROR, "RH_GetConnectNonblockFd manag_malloc is error\n");
                goto _EXIT;
			}
			  struct sockaddr_in flocal;
			  int faddr_len = sizeof(struct sockaddr_in );
			 getpeername(client_socket,(struct sockaddr*)&flocal,&faddr_len);


			memset(pOprHandle, 0 , sizeof(Net_Opreate_Hanle_t));

			pOprHandle->inParam.logFun = inParam->logFun;
			pOprHandle->inParam.statusFun = inParam->statusFun;
			pOprHandle->inParam.cmdfun = inParam->cmdfun;
			pOprHandle->inParam.param = inParam->param;
			pOprHandle->inParam.overtime = inParam->overtime;
			pOprHandle->inParam.heartmsg = inParam->heartmsg;
			pOprHandle->socket = client_socket;
			pOprHandle->serverHandle = serverHandle;
			strncpy(pOprHandle->usermessege.ip, clientip, sizeof(pOprHandle->usermessege.ip));
			pOprHandle->usermessege.nPort =  ntohs(flocal.sin_port);
			
			addServeConNum(serverHandle);
			ret = sdk_pthread_create(&tid, NULL, server_process_clientThread, (void *)(pOprHandle));
			if(ret != 0)
			{
				subServeConNum(serverHandle);
				if(pOprHandle != NULL)
				{
					manag_free(pOprHandle);
				}
				RH_Close((char *)__FILE__, (char *)__func__, client_socket);
				printf("pthreadcreate error:%d,error msg:=%s,port[%u].\n", errno, strerror(errno), inParam->nPort);
				inParam->logFun("pthreadcreat error:%d,error msg:=%s,port[%u].\n", errno, strerror(errno), inParam->nPort);
				continue;
			}

		}
		//sleep(1);
	}
_EXIT:
	//nslog(NS_ERROR, "*********netServer_thread is error code is error error please check code*******\n");
	pthread_detach(pthread_self());
	exit(0);
	return NULL;
}
Sdk_ServerNet_Handle_t sdkserver_init_net(InparamServerNet_t netserverparm)
{
	//Sdk_ServerNet_Handle_t serverHandle = NULL;
	if(netserverparm.cmdfun == NULL || netserverparm.logFun == NULL || netserverparm.statusFun == NULL ||
			netserverparm.nPort <= 0 || netserverparm.overtime <= 0)
	{
		return NULL;
	}
	Net_Server_Handle_t* serverHandle = (Net_Server_Handle_t*)manag_malloc(sizeof(Net_Server_Handle_t));
	if(serverHandle == NULL)
	{
		netserverparm.logFun("sdkserver_init_net is malloc fail\n");
		return serverHandle;
	}
	memset(serverHandle, 0 ,sizeof(Net_Server_Handle_t));
	memcpy(&(serverHandle->inParam), &netserverparm, sizeof(InparamServerNet_t));

	pthread_mutex_init(&(serverHandle->serverlock), NULL);
	serverHandle->pListClient = list_create();

	int ret = sdk_pthread_create(&(serverHandle->servertid), NULL, netServer_thread, (void *)(serverHandle));

	if (ret != 0)
	{
		netserverparm.logFun("crate NetServer thread failed\n");
		 manag_free(serverHandle);
		return NULL;
	}
	return serverHandle;
}


